﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace tiDE.KeyboardManager
{
    [Serializable]
    public class ShortcutManager
    {
        public ShortcutManager()
        {
            Shortcuts = new List<KeyboardShortcut>();
            // Defaults
            Shortcuts.Add(new KeyboardShortcut()
                {
                    IsControl = true,
                    Key = Keys.S,
                    MenuPath = new string[] { "File", "Save", },
                });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = true,
                Key = Keys.S,
                MenuPath = new string[] { "File", "Save All", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = true,
                Key = Keys.B,
                MenuPath = new string[] { "Build", "Build Solution", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = false,
                IsShift = false,
                IsAlt = false,
                Key = Keys.F5,
                MenuPath = new string[] { "Debug", "Start Debugging", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.P,
                MenuPath = new string[] { "File", "Print", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.O,
                MenuPath = new string[] { "File", "Open", "File...", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.O,
                MenuPath = new string[] { "File", "Open", "File", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = false,
                IsShift = false,
                IsAlt = false,
                Key = Keys.F5,
                MenuPath = new string[] { "Debug", "Start Debugging", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.A,
                MenuPath = new string[] { "Edit", "Select All", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.F,
                MenuPath = new string[] { "Edit", "Find and Replace", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.Z,
                MenuPath = new string[] { "Edit", "Undo" },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.R,
                MenuPath = new string[] { "Edit", "Redo", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.C,
                MenuPath = new string[] { "Edit", "Copy", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.X,
                MenuPath = new string[] { "Edit", "Cut", },
            });
            Shortcuts.Add(new KeyboardShortcut()
            {
                IsControl = true,
                IsShift = false,
                IsAlt = false,
                Key = Keys.V,
                MenuPath = new string[] { "Edit", "Paste", },
            });
        }

        public List<KeyboardShortcut> Shortcuts;

        public KeyboardShortcut GetByPath(string[] Path)
        {
            foreach (KeyboardShortcut shortcut in Shortcuts)
            {
                if (shortcut.MenuPath.Length != Path.Length)
                    continue;
                bool success = true;
                for (int i = 0; i < shortcut.MenuPath.Length; i++)
                {
                    if (shortcut.MenuPath[i] != Path[i])
                    {
                        success = false;
                        break;
                    }
                }
                if (success)
                    return shortcut;
            }
            return null;
        }

        /// <summary>
        /// Given a shortcut, it will delete an existing
        /// one with that key combination and add the
        /// provided one in it's place.  If Shortcut.Key
        /// is set to Keys.None, it will delete the shortcut.
        /// </summary>
        public void UpdateShortcut(KeyboardShortcut Shortcut)
        {
            // Remove existing shortcut with that key combination
            int oldIndex = -1;
            int index = 0;
            foreach (KeyboardShortcut shortcut in Shortcuts)
            {
                if (shortcut.IsControl == Shortcut.IsControl &&
                    shortcut.IsAlt == Shortcut.IsAlt &&
                    shortcut.IsShift == Shortcut.IsShift &&
                    shortcut.Key == Shortcut.Key)
                {
                    oldIndex = index;
                    break;
                }
                index++;
            }
            if (oldIndex != -1)
                Shortcuts.RemoveAt(oldIndex);

            if (Shortcut.Key == Keys.None)
                return;

            // Add new one
            index = 0;
            int newIndex = -1;
            foreach (KeyboardShortcut shortcut in Shortcuts)
            {
                if (shortcut.MenuPath.Length != Shortcut.MenuPath.Length)
                    continue;
                bool success = true;
                for (int i = 0; i < shortcut.MenuPath.Length; i++)
                {
                    if (shortcut.MenuPath[i] != Shortcut.MenuPath[i])
                    {
                        success = false;
                        break;
                    }
                }
                if (success)
                {
                    newIndex = index;
                    break;
                }
                index++;
            }
            if (newIndex == -1)
                Shortcuts.Add(Shortcut);
            else
                Shortcuts[newIndex] = Shortcut;
        }

        /// <summary>
        /// Adds the MenuItem to the given Shortcut, or null
        /// </summary>
        /// <param name="Shortcut"></param>
        /// <returns></returns>
        public KeyboardShortcut GetByShortcut(KeyboardShortcut Shortcut)
        {
            foreach (KeyboardShortcut shortcut in Shortcuts)
            {
                if (shortcut.IsControl == Shortcut.IsControl &&
                    shortcut.IsAlt == Shortcut.IsAlt &&
                    shortcut.IsShift == Shortcut.IsShift &&
                    shortcut.Key == Shortcut.Key)
                    return shortcut;
            }
            return null;
        }
    }
}
